﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Storage.Aliyun
{
    class StorageHttp
    {
        HttpWebRequest _client;
        string _url;
        public StorageHttp(string url)
        {
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
            //_client = new HttpClient();
            //_client.Timeout = new TimeSpan(0, 5, 0);
            _url = url;
        }

        

        public bool DoesObjectExist(string bucketName = null, string objectName = null)
        {
            //if (_client == null)
            //    return false;

            _client = (HttpWebRequest)WebRequest.Create(_url);
            try
            {
                _client.AddRange(0, 1);
                using (var resp = _client.GetResponse())
                {
                    return resp.ContentLength > 0;
                }
                //基于httpclient
                //var request = new HttpRequestMessage(HttpMethod.Get, _url);
                //request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(0, 1);
                //var resp = _client.SendAsync(request).GetAwaiter().GetResult();
                //return resp.IsSuccessStatusCode;

            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return false;
            }
        }



        public long GetContentLength(string bucketName = null, string objectName = null)
        {
            //if (_client == null)
            //    return -1;
            _client = (HttpWebRequest)WebRequest.Create(_url);
            try
            {
                //基于httpclient
                //var request = new HttpRequestMessage(HttpMethod.Get, _url);
                //request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(0, 1);
                //var resp = _client.SendAsync(request).GetAwaiter().GetResult();
                //return resp.Content.Headers.ContentRange.Length ?? -1;
                _client.AddRange(0, 1);
                using (var resp = _client.GetResponse())
                {
                    var key = resp.Headers.GetValues("Content-Range").FirstOrDefault()?.Split('/')?.LastOrDefault();
                    long len = -1;
                    long.TryParse(key, out len);
                    return len;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return -1;
            }
        }

        public byte[] GetStreamData(string bucketName, string objectName, long offset, long count)
        {
            //if (_client == null)
            //    return null;
            _client = (HttpWebRequest)WebRequest.Create(_url);
            try
            {

                byte[] data = new byte[count];

                //基于httpclient
                //var request = new HttpRequestMessage(HttpMethod.Get, _url);
                //request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(offset, offset + count);
                //var resp = _client.SendAsync(request).GetAwaiter().GetResult();


                ////using (Stream stream = resp.Content.ReadAsStreamAsync().GetAwaiter().GetResult())//new MemoryStream(Buffer))
                ////{
                ////    try
                ////    {
                ////        stream.Seek(offset, SeekOrigin.Begin);
                ////        stream.Read(data, 0, (int)count);
                ////    }
                ////    catch (Exception e)
                ////    {
                ////        Console.WriteLine(e);
                ////        return null;
                ////    }
                ////}
                //data = resp.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
                _client.AddRange(offset, offset + count);
                using (var resp = _client.GetResponse())
                {
                    var stream = resp.GetResponseStream();
                    var reader = new BinaryReader(stream);
                    data = reader.ReadBytes(data.Length);
                }
                return data;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return null;
            }
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="objectName"></param>
        /// <param name="localFileName"></param>
        /// <returns></returns>
        public bool UploadObject(string bucketName, string objectName, string localFileName)
        {
            try
            {
                _client = (HttpWebRequest)WebRequest.Create(_url);
                _client.Method = "PUT";
                _client.ContentType = "application/octet-stream";

                //每块大小
                int partSize = 0;
                //每片数据
                byte[] parts = new byte[10 * 1024 * 1024];
                using (var request = _client.GetRequestStream())
                {
                    FileStream fs = new FileStream(localFileName, FileMode.Open, FileAccess.Read, share: FileShare.ReadWrite);
                    //分片上传
                    while ((partSize = fs.Read(parts, 0, parts.Length)) > 0)
                    {
                        request.Write(parts, 0, partSize);
                    }
                    fs.Close();
                    fs.Dispose();

                    //一次上传
                    //byte[] bArr = new byte[fs.Length];
                    //fs.Read(bArr, 0, bArr.Length);
                    //fs.Close();
                    // request.bArr(parts, 0, bArr.Length);
                }
                var response = _client.GetResponse() as HttpWebResponse;

                //基于httpclient
                //using (StreamContent stream = new StreamContent(File.OpenRead(localFileName)))
                //{
                //    _client.Timeout = new TimeSpan(0, 20, 0);
                //    //阿里需要添加请求头
                //    //if (_url.Contains("aliyun"))
                //    //    stream.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");
                //    var resp = _client.PutAsync(_url, stream).GetAwaiter().GetResult();
                //    return resp.StatusCode == HttpStatusCode.OK;
                //}
                return response.StatusCode == HttpStatusCode.OK;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public byte[] DownLoadObject(string bucketName, string objectName)
        {
            try
            {
                //基于httpclient
                //var request = new HttpRequestMessage(HttpMethod.Get, _url);
                //var resp = _client.SendAsync(request).GetAwaiter().GetResult();
                //return resp.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();

                _client = (HttpWebRequest)WebRequest.Create(_url);
                _client.Method = "GET";
                using (var resp = _client.GetResponse())
                {
                    var stream = resp.GetResponseStream();
                    var reader = new BinaryReader(stream);
                    var bytes= Encoding.UTF8.GetBytes(reader.ReadString());
                    var file= File.Create("");
                    file.Write(bytes, 0, bytes.Length);
                    return bytes;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public void Dispose()
        {
            if (_client != null)
            {
                _client = null;
            }
        }

        /// <summary>
        /// 可参考Upload
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="objectName"></param>
        /// <param name="localFileName"></param>
        /// <returns></returns>
        public bool MultipartUpload(string bucketName, string objectName, string localFileName)
        {
            throw new NotImplementedException();
        }
    }
}
